/**************************************************************************************
*
*	Copyright (C) 2009 - 2012 Brent Andrew O. Chua - See LICENSE.txt for more info.
*		
*	Filename	-	VertexShaderStage.cpp
*
*	Comments	-	See VertexShaderStage.h
*
**************************************************************************************/
#include "../Include/ComputeShaderStage.h"
#include "../Include/Renderer.h"
#include "../Include/ComputeShader.h"

namespace Pulse
{
	ComputeShaderStage::ComputeShaderStage( void )
		: IShaderStage()
	{

	}

	ComputeShaderStage::~ComputeShaderStage( void )
	{

	}

	void ComputeShaderStage::ClearStates( void )
	{
		m_stateCache.ClearStates();
	}

	void ComputeShaderStage::BindStates( void )
	{
		BindShader();
		BindConstantBuffers();
		BindShaderResourceViews();
		BindSamplerStates();
		BindUnordererdAccessViews();
	}

	void ComputeShaderStage::BindShader( void )
	{
		ID3D11DeviceContext *pDC = (ID3D11DeviceContext*)m_pRenderer->GetNakedDeviceContext();

		if ( m_stateCache.m_pShader )
		{
			ID3D11ComputeShader *pShader = (ID3D11ComputeShader*)m_stateCache.m_pShader->GetNakedShader();

			if ( m_stateCache.m_pShader->GetShaderType() == EShader::COMPUTE )
			{
				pDC->CSSetShader( pShader, 0, 0 );
			}
			else
			{
				PSX_PushError( "Invalid Shader type to bind. Must specify a pixel shader type." );
			}
		}
		else
		{
			pDC->CSSetShader( PSX_NULL, 0, 0 );
		}
	}
	
	void ComputeShaderStage::BindConstantBuffers( void )
	{
		ID3D11DeviceContext *pDC = (ID3D11DeviceContext*)m_pRenderer->GetNakedDeviceContext();

		pDC->CSSetConstantBuffers( 0, PSX_NUM_CONSTANT_BUFFER_SLOT, (ID3D11Buffer * const *)m_stateCache.m_pD3DConstantBuffers );
	}
	
	void ComputeShaderStage::BindSamplerStates( void )
	{
		ID3D11DeviceContext *pDC = (ID3D11DeviceContext*)m_pRenderer->GetNakedDeviceContext();

		pDC->CSSetSamplers( 0, PSX_NUM_SAMPLER_SLOT, (ID3D11SamplerState * const *)m_stateCache.m_pD3DSamplerStates );
	}
	
	void ComputeShaderStage::BindShaderResourceViews( void )
	{
		ID3D11DeviceContext *pDC = (ID3D11DeviceContext*)m_pRenderer->GetNakedDeviceContext();
		pDC->CSSetShaderResources( 0, PSX_NUM_INPUT_RESOURCE_SLOT, (ID3D11ShaderResourceView * const *)m_stateCache.m_pD3DShaderResources );
	}

	void ComputeShaderStage::BindUnordererdAccessViews( void )
	{
		// NOTE: We need to fix this once we're using append/consume buffers.
		const UINT initialCounts[PSX_NUM_UAV_SLOT] = { -1 }; // Unused.

		ID3D11DeviceContext *pDC = (ID3D11DeviceContext*)m_pRenderer->GetNakedDeviceContext();
		pDC->CSSetUnorderedAccessViews( 0, PSX_NUM_UAV_SLOT, (ID3D11UnorderedAccessView * const *)m_stateCache.m_pD3DUnorderedAccessViews, initialCounts );
	}
}